home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-09 | 45.7 KB | 1,688 lines | [TEXT/CWIE] |
- // MSAEAccessors.c
- //
- // Original version by Jon Lansdell and Nigel Humphreys.
- // 4.0 and 3.1 updates by Greg Sutton.
- // ©Apple Computer Inc 1996, all rights reserved.
-
- /*
- Changes for 3.1
-
- 14-Nov-95 : GS : Removed reliance on compiler setting local variable to zero
- in WindowFormAbsolutePosition() and TextFormAbsolutePosition().
-
- Changes for 4.0
-
- 29-Feb-96 : GS : Added differentiation between windows and documents.
- 29-Feb-96 : GS : Added resolution of menus and menu items.
- */
-
- #include "MSAccessors.h"
-
- #include <Menus.h>
- #ifdef THINK_C
- #include "PLStrs.h"
- #else
- #include <PLStringFuncs.h>
- #endif
- #include <Scrap.h>
- #include <TextEdit.h>
- #include <AEObjects.h>
- #include <AEPackObject.h>
- #include <AERegistry.h>
- #include "MSGlobals.h"
- #include "MSUtils.h"
- #include "MSAEUtils.h"
- #include "MSWindow.h"
- #include "MSFile.h"
- #include "MSAppleEvents.h"
-
- #include "MSToken.h"
- #include "MSAETextUtils.h"
- #include "MSAEWindowUtils.h"
- #include "MSAEMenuUtils.h"
-
-
- #pragma segment AppleEvent
-
- // Install accessors that are used when AEResolve is called to convert
- // object specifiers into internal representations (tokens).
-
- OSErr InstallAccessors(void)
- {
- OSErr err;
-
- err = AEInstallObjectAccessor(cApplication, typeNull, NewOSLAccessorProc(ApplicationFromNullAccessor), 0, false);
- err = AEInstallObjectAccessor(cWindow, typeNull, NewOSLAccessorProc(WindowFromNullAccessor), 0, false);
- err = AEInstallObjectAccessor(cDocument, typeNull, NewOSLAccessorProc(DocumentFromNullAccessor), 0, false);
- err = AEInstallObjectAccessor(cProperty, typeNull, NewOSLAccessorProc(PropertyFromNullAccessor), 0, false);
- err = AEInstallObjectAccessor(cMenu, typeNull, NewOSLAccessorProc(MenuFromNullAccessor), 0, false);
-
- err = AEInstallObjectAccessor(cWindow, typeMyAppl, NewOSLAccessorProc(WindowFromNullAccessor), 0, false);
- err = AEInstallObjectAccessor(cDocument, typeMyAppl, NewOSLAccessorProc(DocumentFromNullAccessor), 0, false);
- err = AEInstallObjectAccessor(cProperty, typeMyAppl, NewOSLAccessorProc(PropertyFromApplAccessor), 0, false);
- err = AEInstallObjectAccessor(cMenu, typeMyAppl, NewOSLAccessorProc(MenuFromNullAccessor), 0, false);
-
- err = AEInstallObjectAccessor(cProperty, typeMyWndw, NewOSLAccessorProc(PropertyFromWndwAccessor), 0, false);
-
- // Handle text from a window
- // e.g. some character of last document
- err = AEInstallObjectAccessor(cInsertionPoint,typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cChar, typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cText, typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cWord, typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cParagraph, typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cProperty, typeMyDocument, NewOSLAccessorProc(PropertyFromDocumentAccessor), 0, false);
-
- // Handle text items within text items
- // e.g. last word of first paragraph of front document
- err = AEInstallObjectAccessor(cInsertionPoint,typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cChar, typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cText, typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cWord, typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cParagraph, typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cProperty, typeMyText, NewOSLAccessorProc(PropertyFromTextAccessor), 0, false);
-
- // Menus
- err = AEInstallObjectAccessor(cMenuItem, typeMyMenu, NewOSLAccessorProc(MenuItemFromMenuAccessor), 0, false);
- err = AEInstallObjectAccessor(cProperty, typeMyMenu, NewOSLAccessorProc(PropertyFromMenuAccessor), 0, false);
-
- // Menu Items
- err = AEInstallObjectAccessor(cProperty, typeMyMenuItem, NewOSLAccessorProc(PropertyFromMenuItemAccessor), 0, false);
-
- // Handle text items from lists (of hopefully text items) also
- // e.g. every word of every paragraph of front document
- // or even - every word of every character of every paragraph of front document
- err = AEInstallObjectAccessor(cInsertionPoint,typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cChar, typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cText, typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cWord, typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cParagraph, typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
- err = AEInstallObjectAccessor(cProperty, typeAEList, NewOSLAccessorProc(PropertyFromListAccessor), 0, false);
-
-
- // This is for 'select insertion point before contents of document 1'
- err = AEInstallObjectAccessor(cInsertionPoint, typeMyWindowProp, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false);
-
- // This accessor is for getting properties of window properties
- // e.g. font of contents of document 1
- // Relies on ability to coerce from a window property to text
- // for certain properties.
- err = AEInstallObjectAccessor(cProperty, typeMyDocumentProp, NewOSLAccessorProc(PropertyFromTextAccessor), 0, false);
-
- return(err);
- }
-
-
- // Given selectionData of formAbsolutePosition for a window this routine returns
- // a WindowToken descriptor for specified window.
- //
- // e.g. tell application "MenuScripter"
- // window 1
- // --first document
- // --some window
- // --every window
- // end tell
-
- OSErr WindowFormAbsolutePosition(const AEDesc *selectionData, AEDesc* result)
- {
- AEDesc itemDesc = {typeNull, NULL};
- short windowCount,
- index;
- OSErr err;
-
- windowCount = CountWindows();
-
- if (! windowCount)
- return(errAEIllegalIndex);
-
- if (typeAbsoluteOrdinal == selectionData->descriptorType)
- {
- err = noErr;
-
- switch (*(DescType *)*selectionData->dataHandle)
- {
- case kAEFirst:
- index = 1;
- break;
-
- case kAELast:
- index = windowCount;
- break;
-
- case kAEMiddle:
- index = (windowCount + 1) / 2;
- break;
-
- case kAEAny:
- index = (Random() % windowCount) + 1;
- break;
-
- case kAEAll:
- err = AECreateList(NULL, 0 , false, result);
- if (noErr != err) goto done;
-
- for (index = 1; index <= windowCount; index++)
- {
- err = GetDescOfNthWindow(index, &itemDesc);
- if (noErr != err) goto done;
-
- err = AEPutDesc(result, 0, &itemDesc);
- if (noErr != err) goto done;
-
- if (itemDesc.dataHandle)
- AEDisposeDesc(&itemDesc);
- }
-
- goto done; // We have created our list descriptor
- break; // so we can just tidy up and return.
-
- default:
- err = errAETypeError;
- }
- }
- else
- err = GetIntegerFromDescriptor(selectionData, &index);
-
- if (noErr != err) goto done;
-
- if (index < 0) // Handle negative indexes
- index = windowCount + index + 1;
-
- if (index > windowCount || index <= 0)
- err = errAEIllegalIndex;
- else
- err = GetDescOfNthWindow(index, result);
-
- done:
- if (itemDesc.dataHandle)
- AEDisposeDesc(&itemDesc);
-
- return(err);
- } // WindowFormAbsolutePosition
-
-
- // Given a formName descriptor in selectionData, this routine returns a
- // WindowToken descriptor for the window with that name.
- //
- // e.g. tell application "MenuScripter"
- // document "Untitled"
- // end tell
-
- OSErr WindowFormName(const AEDesc *selectionData, AEDesc* result)
- {
- Str255 name;
- OSErr err;
-
- // This tries to coerce it first
- err = GetPStringFromDescriptor(selectionData, name);
- if (noErr != err) goto done;
-
- err = GetDescOfNamedWindow(name, result);
-
- done:
- return(err);
- }
-
-
- // Get a WindowToken descriptor for a window or document object specifier
- // from NULL (or the application). Only handles formAbsolutePosition and formName
- //
- // e.g. tell application "MenuScripter"
- // window 1
- // --first document
- // --document "Untitled"
- // --every window
- // end tell
-
- pascal OSErr WindowFromNullAccessor(DescType wantClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(container,theRefCon)
- #endif
-
- OSErr err;
-
- // Can only handle cWindow and cDocument
- if ( wantClass != cWindow )
- return errAEWrongDataType;
-
- // Can only handle typeNull and typeMyAppl
- if ( containerClass != typeNull && containerClass != typeMyAppl )
- return errAENoSuchObject;
-
- switch (form)
- {
- case formAbsolutePosition:
- err = WindowFormAbsolutePosition(selectionData, value);
- break;
-
- case formName:
- err = WindowFormName(selectionData, value);
- break;
-
- default:
- err = errAEBadTestKey;
- }
-
- return err;
- } // WindowFromNullAccessor
-
-
- OSErr DocumentFormAbsolutePosition(const AEDesc *selectionData, AEDesc* result)
- {
- AEDesc itemDesc = {typeNull, NULL};
- short aCount,
- index;
- OSErr err;
-
- aCount = CountDocuments();
-
- if ( ! aCount )
- return(errAEIllegalIndex);
-
- if ( typeAbsoluteOrdinal == selectionData->descriptorType )
- {
- err = noErr;
-
- switch (*(DescType *)*selectionData->dataHandle)
- {
- case kAEFirst:
- index = 1;
- break;
-
- case kAELast:
- index = aCount;
- break;
-
- case kAEMiddle:
- index = ( aCount + 1 ) / 2;
- break;
-
- case kAEAny:
- index = ( Random() % aCount ) + 1;
- break;
-
- case kAEAll:
- err = AECreateList( NULL, 0 , false, result );
- if (noErr != err) goto done;
-
- for ( index = 1; index <= aCount; index++ )
- {
- err = GetDescOfNthDocument( index, &itemDesc );
- if (noErr != err) goto done;
-
- err = AEPutDesc( result, 0, &itemDesc );
- if (noErr != err) goto done;
-
- (void)AEDisposeDesc( &itemDesc );
- }
-
- goto done; // We have created our list descriptor
- break; // so we can just tidy up and return.
-
- default:
- err = errAETypeError;
- }
- }
- else
- err = GetIntegerFromDescriptor(selectionData, &index);
-
- if (noErr != err) goto done;
-
- if (index < 0) // Handle negative indexes
- index = aCount + index + 1;
-
- if (index > aCount || index <= 0)
- err = errAEIllegalIndex;
- else
- err = GetDescOfNthDocument(index, result);
-
- done:
- (void)AEDisposeDesc(&itemDesc);
-
- return(err);
- } // DocumentFormAbsolutePosition
-
-
- OSErr DocumentFormName(const AEDesc *selectionData, AEDesc* result)
- {
- Str255 name;
- OSErr err;
-
- // This tries to coerce it first
- err = GetPStringFromDescriptor(selectionData, name);
- if (noErr != err) goto done;
-
- err = GetDescOfNamedDocument(name, result);
-
- done:
- return(err);
- }
-
-
- pascal OSErr DocumentFromNullAccessor(DescType wantClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused (container,theRefCon)
- #endif
-
- OSErr err;
-
- // Can only handle cWindow and cDocument
- if ( wantClass != cDocument )
- return errAEWrongDataType;
-
- // Can only handle typeNull and typeMyAppl
- if ( containerClass != typeNull && containerClass != typeMyAppl )
- return errAENoSuchObject;
-
- switch (form)
- {
- case formAbsolutePosition:
- err = DocumentFormAbsolutePosition( selectionData, value );
- break;
-
- case formName:
- err = DocumentFormName( selectionData, value );
- break;
-
- default:
- err = errAEBadTestKey;
- }
-
- return err;
- } // DocumentFromNullAccessor
-
-
- pascal OSErr ApplicationFromNullAccessor(DescType wantClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(container,selectionData,theRefCon)
- #endif
-
- OSErr myErr;
- AppToken theApp;
- AEDesc resultDesc;
-
- value->dataHandle = nil;
- resultDesc.dataHandle = nil;
-
- /*
- should only be called with wantClass = cWindow and
- with containerClass = typeNull.
- Currently accept as either formName or formAbsolutePosition
- */
-
- if ((wantClass != cApplication) || (containerClass != typeNull) ||
- !((form == formName) || (form == formAbsolutePosition)))
- return(errAEWrongDataType);
-
- if ((form == formName) || (form == formAbsolutePosition))
- {
- theApp.highLongOfPSN = 0;
- theApp.lowLongOfPSN = kCurrentProcess;
- }
-
- myErr = AECreateDesc(typeMyAppl, (Ptr)&theApp, sizeof(theApp), value);
-
- return(myErr);
- } /* ApplicationFromNullAccessor */
-
-
- // Given a formAbsolutePosition selectionData descriptor and a TextToken from
- // which to index from. This routine returns a TextToken descriptor for the
- // text specified.
- //
- // e.g. tell application "MenuScripter"
- // first word of window 1 -- window one will be dealt with in
- // -- WindowFromNullAccessor().
- // --some character of middle paragraph of last document
- // -- container token will be a paragraph
- // end tell
-
- OSErr TextFormAbsolutePosition(TextToken* containerToken, AEDesc* selectionData,
- DescType wantClass, AEDesc* result)
- {
- DPtr docPtr;
- short elementCount;
- AEDesc aDesc = {typeNull, NULL};
- long index;
- OSErr err;
-
- docPtr = DPtrFromWindowPtr(containerToken->tokenWindow);
-
- if (! docPtr)
- {
- err = errAENoSuchObject;
- goto done;
- }
-
- err = CountTextElements(docPtr->theText, containerToken->tokenOffset,
- containerToken->tokenLength, wantClass, &elementCount);
- if (noErr != err) goto done;
-
- if (typeAbsoluteOrdinal == selectionData->descriptorType)
- {
- err = noErr;
-
- switch (*(DescType *)*selectionData->dataHandle)
- {
- case kAEFirst:
- index = 1;
- break;
-
- case kAELast:
- index = elementCount;
- break;
-
- case kAEMiddle:
- index = (elementCount + 1) / 2;
- break;
-
- case kAEAny:
- index = (Random() % elementCount) + 1;
- break;
-
- case kAEAll:
- err = AECreateList(NULL, 0 , false, result);
-
- for (index = 1; index <= elementCount; index++)
- {
- if (noErr == (err = GetDescOfNthTextElement(index, wantClass,
- containerToken, &aDesc)))
- {
- err = AEPutDesc(result, 0, &aDesc);
- AEDisposeDesc(&aDesc);
- }
- }
- goto done; // Created our result - clean up and return
- break;
-
- default:
- err = errAETypeError;
- }
- }
- else // Try and get an index out of the descriptor
- err = GetLongIntFromDescriptor(selectionData, &index);
-
- if (noErr != err) goto done;
- // kAEAll has already created it's list
- err = GetDescOfNthTextElement(index, wantClass, // Checks for negatives and
- containerToken, result); // out of range.
-
- done:
- if (aDesc.dataHandle)
- AEDisposeDesc(&aDesc);
-
- return(err);
- }
-
-
- // Given a TextToken container and a formRange descriptor. This routine
- // creates a TextToken descriptor starting at the the beginning of the
- // first item in the range and ending at the end of the last item in the range.
- //
- // e.g. tell application "MenuScripter"
- // paragraphs 2 thru 3 of document 1
- // end tell
-
- OSErr TextFormRange(TextToken* containerToken, AEDesc* selectionData,
- DescType wantClass, AEDesc* result)
- {
- #ifdef __MWERKS__
- #pragma unused(wantClass)
- #endif
-
- AEDesc selectionRecord = {typeNull, NULL};
- TextToken startToken,
- stopToken;
- DescType returnedType;
- Size actualSize;
- OSErr err;
-
- // coerce the selection data into an AERecord
- err = AECoerceDesc(selectionData, typeAERecord, &selectionRecord);
- if (noErr != err) goto done;
-
- // get the start object as a text token this will reenter
- // TextElemFromTextAccessor() but as formAbsolutePosition via
- // our installed coercion handler CoerceObjToAnything()
- // because the keyAERangeStart parameter is actually an object specifier.
- err = AEGetKeyPtr(&selectionRecord, keyAERangeStart, typeMyText,
- &returnedType, (Ptr)&startToken, sizeof(startToken), &actualSize);
- if (noErr != err) goto done;
-
- // now do the same for the stop object
- err = AEGetKeyPtr(&selectionRecord, keyAERangeStop, typeMyText,
- &returnedType, (Ptr)&stopToken, sizeof(stopToken), &actualSize);
- if (noErr != err) goto done;
-
- if (containerToken->tokenWindow != startToken.tokenWindow
- || containerToken->tokenWindow != stopToken.tokenWindow)
- {
- err = errAECorruptData; // or whatever
- goto done;
- }
-
- // Use startToken to create result descriptor
- startToken.tokenLength = stopToken.tokenOffset + stopToken.tokenLength - startToken.tokenOffset;
-
- err = AECreateDesc(typeMyText, (Ptr)&startToken, sizeof(startToken), result);
-
- done:
- if (selectionRecord.dataHandle)
- AEDisposeDesc(&selectionRecord);
-
- return(err);
- }
-
-
- // Given a container TextToken and a formRelativePosition selectionData descriptor
- // this routine returns a TextToken descriptor to the reative wantClass object
- // specified.
- // This routine currently only handles relative positions for a wantClass
- // of cInsertionPoint.
- //
- // e.g. tell application "MenuScripter"
- // insertion point after word 5 of document 1
- // end tell
-
- OSErr TextFormRelativePosition(TextToken* containerToken, AEDesc* selectionData,
- DescType wantClass, AEDesc* result)
- {
- TextToken aTextToken;
- DescType aPosition;
- OSErr err;
-
- aTextToken.tokenWindow = containerToken->tokenWindow;
-
- switch (wantClass)
- {
- case cInsertionPoint:
- err = GetEnumeratedFromDescriptor(selectionData, &aPosition);
-
- switch (aPosition)
- {
- case kAEPrevious:
- case kAEBefore:
- case kAEBeginning:
- // No change to offset - just 0 length now
- // containerToken.tokenOffset = containerToken.tokenOffset;
- aTextToken.tokenOffset = containerToken->tokenOffset;
- aTextToken.tokenLength = 0;
- break;
-
- case kAENext:
- case kAEAfter:
- case kAEEnd:
- aTextToken.tokenOffset = containerToken->tokenOffset + containerToken->tokenLength;
- aTextToken.tokenLength = 0;
- break;
-
- default:
- err = errAEIllegalIndex;
- }
- break;
-
- default:
- err = errAEWrongDataType; // Could do cChar, cWord… but this is only a sample
- }
-
- if (noErr != err) goto done;
-
- err = AECreateDesc(typeMyText, (Ptr)&aTextToken, sizeof(aTextToken), result);
-
- done:
- return(err);
- }
-
-
- // Tries to create a TextToken descriptor given a container which may
- // be a TextToken descriptor or a WindowToken descriptor. A
- // selectionData descriptor which can be of formAbsolutePosition,
- // formRange or formRelativePosition, and a wantClass which should
- // be cInsertionPoint, cChar, cText, cWord or cParagraph.
- //
- // e.g. tell application "MenuScripter"
- // first word of document 1 -- document 1 will go through WindowFromNullAccessor()
- // -- which will return a WindowToken descriptor. This
- // -- descriptor will then be coerced to a TextToken
- // -- descriptor and used as the container.
- // end tell
-
- pascal OSErr TextElemFromTextAccessor(DescType wantClass,
- AEDesc *container,
- DescType containerClass,
- DescType form,
- AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(containerClass)
- #endif
-
- TextToken containerToken;
- long index;
- long itemCount;
- AEDesc aDesc = {typeNull, NULL},
- resultDesc = {typeNull, NULL};
- DescType returnedType;
- Size actualSize;
- OSErr myErr;
-
- // If it's a list then we need to call this accessor for every
- // item within the list (which could of course be more lists).
- if (typeAEList == container->descriptorType)
- {
- myErr = AECreateList(NULL, 0 , false, value); // Result will also be a list of items
- if (noErr != myErr) goto done;
- myErr = AECountItems(container, &itemCount);
- if (noErr != myErr) goto done;
-
- for (index = 1; index <= itemCount; index++) // Do in forward order
- {
- myErr = AEGetNthDesc(container, index, typeWildCard, &returnedType, &aDesc);
-
- if (noErr == myErr) // Call this function recursively if necessary
- myErr = TextElemFromTextAccessor(wantClass, &aDesc, returnedType,
- form, selectionData, &resultDesc, theRefCon);
-
- if (noErr == myErr) // Add item to the end of our list
- myErr = AEPutDesc(value, 0, &resultDesc);
-
- if (aDesc.dataHandle)
- AEDisposeDesc(&aDesc);
- if (resultDesc.dataHandle)
- AEDisposeDesc(&resultDesc);
- }
- }
- else
- { // We have a coercion handler from document to text
- myErr = AECoerceDesc(container, typeMyText, &aDesc);
- if (noErr != myErr) goto done;
-
- // Get the containing TextToken
- GetRawDataFromDescriptor(&aDesc, (Ptr)&containerToken, sizeof(containerToken), &actualSize);
-
- switch (form)
- {
- case formAbsolutePosition:
- myErr = TextFormAbsolutePosition(&containerToken, selectionData,
- wantClass, value);
- break;
-
- case formRange:
- myErr = TextFormRange(&containerToken, selectionData,
- wantClass, value);
- break;
-
- case formRelativePosition:
- myErr = TextFormRelativePosition(&containerToken, selectionData,
- wantClass, value);
- break;
-
- default:
- myErr = errAEBadKeyForm;
- }
- }
-
- done:
- if (aDesc.dataHandle)
- AEDisposeDesc(&aDesc);
-
- return(myErr);
- } // TextElemFromTextAccessor
-
-
- // Given a TextToken descriptor as a container convert this into
- // a TextPropToken descriptor for the property.
-
- pascal OSErr PropertyFromTextAccessor(DescType wantClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused (theRefCon, containerClass)
- #endif
-
- AEDesc textDesc = {typeNull, NULL},
- propertyDesc = {typeNull, NULL};
- Size actualSize;
- TextToken aTextToken;
- TextPropToken aTextPropToken;
- DescType aProperty;
- OSErr err;
-
- if (cProperty != wantClass || formPropertyID != form)
- return(errAEWrongDataType);
-
- // Try and coerce to a TextToken descriptor
- err = AECoerceDesc(container, typeMyText, &textDesc);
- if (noErr != err) goto done;
-
- // Get the TextToken
- GetRawDataFromDescriptor(&textDesc, (Ptr)&aTextToken,
- sizeof(aTextToken), &actualSize);
-
- // Make sure the selection data is typeType
- err = AECoerceDesc(selectionData, typeType, &propertyDesc);
- if (noErr != err) goto done;
-
- // Get the property
- GetRawDataFromDescriptor(&propertyDesc, (Ptr)&aProperty,
- sizeof(aProperty), &actualSize);
-
- // Combine the two into single token
- aTextPropToken.tokenTextToken = aTextToken;
- aTextPropToken.tokenProperty = aProperty;
-
- err = AECreateDesc(typeMyTextProp, (Ptr)&aTextPropToken,
- sizeof(aTextPropToken), value);
-
- done:
- (void)AEDisposeDesc(&textDesc);
- (void)AEDisposeDesc(&propertyDesc);
-
- return(err);
- } // PropertyFromTextAccessor
-
-
- // Given a WindowToken descriptor as a container convert this into
- // a WindowPropToken descriptor for the property.
-
- pascal OSErr PropertyFromWndwAccessor(DescType wantClass,
- AEDesc *container,
- DescType containerClass,
- DescType form,
- AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(containerClass)
- #endif
-
- long itemCount,
- index;
- AEDesc resultDesc = {typeNull, NULL},
- windowDesc = {typeNull, NULL},
- propDesc = {typeNull, NULL};
- Size actualSize;
- DescType returnedType;
- WindowToken theWindowToken;
- WindowPropToken myWindowProp;
- OSErr err;
-
- if (typeAEList == container->descriptorType)
- {
- err = AECreateList(NULL, 0 , false, value); // Result will also be a list of items
- if (noErr != err) goto done;
- err = AECountItems(container, &itemCount);
- if (noErr != err) goto done;
-
- for (index = 1; index <= itemCount; index++) // Do in forward order
- {
- err = AEGetNthDesc(container, index, typeWildCard, &returnedType, &windowDesc);
-
- if (noErr == err) // Recursively call this routine
- // - could be another list.
- err = PropertyFromWndwAccessor(wantClass, &windowDesc, windowDesc.descriptorType,
- form, selectionData, &resultDesc, theRefCon);
-
- if (noErr == err) // Add item to the end of our list
- err = AEPutDesc(value, 0, &resultDesc);
-
- if (windowDesc.dataHandle)
- AEDisposeDesc(&windowDesc);
- if (resultDesc.dataHandle)
- AEDisposeDesc(&resultDesc);
- }
- }
- else
- { // get the window token - it's the container
-
- err = AECoerceDesc(container, typeMyWndw, &windowDesc);
- GetRawDataFromDescriptor(&windowDesc, (Ptr)&theWindowToken,
- sizeof(theWindowToken), &actualSize);
-
- // Check the window exists
-
- if (theWindowToken.tokenWindow == NULL)
- err = errAEIllegalIndex;
- else
- { // get the property - it's in the selection data
-
- err = AECoerceDesc(selectionData, typeType, &propDesc);
- GetRawDataFromDescriptor(&propDesc, (Ptr)&returnedType,
- sizeof(returnedType), &actualSize);
-
- // Combine the two into single token
-
- myWindowProp.tokenWindowToken = theWindowToken;
- myWindowProp.tokenProperty = returnedType;
-
- err = AECreateDesc(typeMyWindowProp, (Ptr)&myWindowProp,
- sizeof(myWindowProp), value);
- }
- }
-
- done:
- if (windowDesc.dataHandle)
- AEDisposeDesc(&windowDesc);
- if (propDesc.dataHandle)
- AEDisposeDesc(&propDesc);
- if (resultDesc.dataHandle)
- AEDisposeDesc(&resultDesc);
-
- return(err);
- } // PropertyFromWndwAccessor
-
-
- pascal OSErr PropertyFromDocumentAccessor(DescType wantClass,
- AEDesc *container,
- DescType containerClass,
- DescType form,
- AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(containerClass)
- #endif
-
- long itemCount,
- index;
- AEDesc resultDesc = {typeNull, NULL},
- windowDesc = {typeNull, NULL},
- propDesc = {typeNull, NULL};
- Size actualSize;
- DescType returnedType;
- WindowToken theWindowToken;
- WindowPropToken myWindowProp;
- OSErr err;
-
- if (typeAEList == container->descriptorType)
- {
- err = AECreateList(NULL, 0 , false, value); // Result will also be a list of items
- if (noErr != err) goto done;
- err = AECountItems(container, &itemCount);
- if (noErr != err) goto done;
-
- for (index = 1; index <= itemCount; index++) // Do in forward order
- {
- err = AEGetNthDesc(container, index, typeWildCard, &returnedType, &windowDesc);
-
- if (noErr == err) // Recursively call this routine
- // - could be another list.
- err = PropertyFromDocumentAccessor(wantClass, &windowDesc, windowDesc.descriptorType,
- form, selectionData, &resultDesc, theRefCon);
-
- if (noErr == err) // Add item to the end of our list
- err = AEPutDesc(value, 0, &resultDesc);
-
- (void)AEDisposeDesc(&windowDesc);
- (void)AEDisposeDesc(&resultDesc);
- }
- }
- else
- { // get the window token - it's the container
-
- err = AECoerceDesc(container, typeMyDocument, &windowDesc);
- GetRawDataFromDescriptor(&windowDesc, (Ptr)&theWindowToken,
- sizeof(theWindowToken), &actualSize);
-
- // Check the window exists
-
- if (theWindowToken.tokenWindow == NULL)
- err = errAEIllegalIndex;
- else
- { // get the property - it's in the selection data
-
- err = AECoerceDesc(selectionData, typeType, &propDesc);
- GetRawDataFromDescriptor(&propDesc, (Ptr)&returnedType,
- sizeof(returnedType), &actualSize);
-
- // Combine the two into single token
-
- myWindowProp.tokenWindowToken = theWindowToken;
- myWindowProp.tokenProperty = returnedType;
-
- err = AECreateDesc(typeMyDocumentProp, (Ptr)&myWindowProp,
- sizeof(myWindowProp), value);
- }
- }
-
- done:
- (void)AEDisposeDesc(&windowDesc);
- (void)AEDisposeDesc(&propDesc);
- (void)AEDisposeDesc(&resultDesc);
-
- return(err);
- } // PropertyFromDocumentAccessor
-
-
- pascal OSErr PropertyFromNullAccessor(DescType wantClass,
- AEDesc *container,
- DescType containerClass,
- DescType form,
- AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused (container, containerClass)
- #endif
-
- AEDesc aDesc = {typeNull, NULL};
- OSErr err;
-
- if ((wantClass != cProperty) || (form != formPropertyID))
- return(errAEWrongDataType);
-
- switch (*(DescType *)*selectionData->dataHandle)
- {
- case pSelection: // The selection defaults to the front window
- // selection.
- err = GetDescOfNthDocument( 1, &aDesc ); // Disposed of at end
- if (noErr != err) goto done;
- err = PropertyFromDocumentAccessor(wantClass, &aDesc, typeMyDocument, form,
- selectionData, value, theRefCon);
- break;
-
- default: // Otherwise try an application property - it is fron NULL
- err = PropertyFromApplAccessor(wantClass, &aDesc, typeMyWndw, form,
- selectionData, value, theRefCon);
- }
-
- done:
- (void)AEDisposeDesc( &aDesc );
-
- return err;
- }
-
-
- // Convert a list of Token descriptors to a list of Property Token descriptors.
- // Only TextTokens and WindowTokens are supported in this version.
-
- OSErr TokenListToPropertyList(AEDesc* tokenList, DescType aProperty, AEDesc* result)
- {
- AEDesc aDesc = {typeNull, NULL},
- resultDesc = {typeNull, NULL};
- DescType returnedType;
- long itemCount,
- index;
- WindowPropToken aWindowPropToken;
- TextPropToken aTextPropToken;
- Size actualSize;
- OSErr err;
-
- err = AECreateList(NULL, 0 , false, result); // Result will also be a list of items
- if (noErr != err) goto done;
- err = AECountItems(tokenList, &itemCount); // Will return an error if not of type typeAEList
- if (noErr != err) goto done;
-
- for (index = 1; index <= itemCount; index++) // Do in forward order
- {
- err = AEGetNthDesc(tokenList, index, typeWildCard, &returnedType, &aDesc);
-
- if (noErr == err) // Create appropriate property token
- switch (aDesc.descriptorType)
- {
- case typeMyWndw:
- GetRawDataFromDescriptor(&aDesc, (Ptr)&aWindowPropToken,
- sizeof(WindowToken), &actualSize);
- aWindowPropToken.tokenProperty = aProperty;
- err = AECreateDesc(typeMyWindowProp, (Ptr)&aWindowPropToken,
- sizeof(aWindowPropToken), &resultDesc);
- break;
-
- case typeMyText:
- GetRawDataFromDescriptor(&aDesc, (Ptr)&aTextPropToken,
- sizeof(TextToken), &actualSize);
- aTextPropToken.tokenProperty = aProperty;
- err = AECreateDesc(typeMyTextProp, (Ptr)&aTextPropToken,
- sizeof(aTextPropToken), &resultDesc);
- break;
-
- case typeAEList: // Recursive call if a list
- err = TokenListToPropertyList(&aDesc, aProperty, &resultDesc);
- break;
-
- default: // May already be a property token
- err = errAEBadListItem;
- }
-
- if (noErr == err) // Add item to the end of our list
- err = AEPutDesc(result, 0, &resultDesc);
-
- if (aDesc.dataHandle)
- AEDisposeDesc(&aDesc);
- if (resultDesc.dataHandle)
- AEDisposeDesc(&resultDesc);
-
- err = noErr; // Try and do all the items we can in the list
- }
-
- done:
- return(err);
- }
-
-
- // Given a container that is a list of Token descriptors, this routine
- // returns a list of PropToken descriptors.
-
- pascal OSErr PropertyFromListAccessor(DescType wantClass,
- AEDesc *container,
- DescType containerClass,
- DescType form,
- AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(containerClass, theRefCon)
- #endif
-
- OSErr err;
-
- if (wantClass != cProperty && form != formPropertyID)
- return(errAEBadKeyForm);
-
- err = TokenListToPropertyList(container, *(DescType *)*selectionData->dataHandle, value);
-
- return(err);
- }
-
-
- // Given a AppToken descriptor as a container convert this into
- // a WindowPropToken descriptor for the property.
-
- pascal OSErr PropertyFromApplAccessor(DescType wantClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused (theRefCon, containerClass)
- #endif
-
- OSErr myErr;
- OSErr ignoreErr;
- AppToken theApplToken;
- DescType theProperty;
- AEDesc applDesc;
- AEDesc propDesc;
- Size actualSize;
- AppPropToken myApplProp;
-
- value->dataHandle = nil;
- applDesc.dataHandle = nil;
- propDesc.dataHandle = nil;
-
- if ((wantClass != cProperty) ||
- (form != formPropertyID))
- {
- return(errAEWrongDataType);
- }
-
- // get the application token - it's the container
-
- myErr = AECoerceDesc(container, typeMyAppl, &applDesc);
- GetRawDataFromDescriptor(&applDesc, (Ptr)&theApplToken,
- sizeof(theApplToken), &actualSize);
-
- // get the property - it's in the selection data
-
- myErr = AECoerceDesc(selectionData, typeType, &propDesc);
- GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty,
- sizeof(theProperty), &actualSize);
-
- // Combine the two into single token
-
- myApplProp.tokenAppToken = theApplToken;
- myApplProp.tokenProperty = theProperty;
-
- myErr = AECreateDesc(typeMyApplProp, (Ptr)&myApplProp,
- sizeof(myApplProp), value);
-
- if (applDesc.dataHandle)
- ignoreErr = AEDisposeDesc(&applDesc);
-
- if (propDesc.dataHandle)
- ignoreErr = AEDisposeDesc(&propDesc);
-
- return(myErr);
- } // PropertyFromApplAccessor
-
-
- pascal OSErr PropertyFromWinPropertyAccessor(DescType wantClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(wantClass, containerClass, form, theRefCon)
- #endif
-
- OSErr myErr;
- OSErr ignoreErr;
- WindowPropToken theWindowPropToken;
- AEDesc newDesc, propDesc;
- Size tokenSize;
- DPtr theDocument;
- TextToken theTextToken;
- DescType theProperty;
- Size actualSize;
- TextPropToken myTextProp;
-
- // the container is a window property token. Get the token for this
- // and check that it is valid to get a property of this property
-
- myErr = AECoerceDesc(container, typeMyWindowProp, &newDesc);
-
- if (myErr)
- return(myErr);
-
- GetRawDataFromDescriptor(&newDesc, (Ptr)&theWindowPropToken,
- sizeof(theWindowPropToken), &tokenSize);
-
- // if the property is pSelection, we then want to convert this to a text token
- // and then return a text property token
-
- if (theWindowPropToken.tokenProperty == pSelection)
- {
- theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken.tokenWindow);
-
- // build a text token to represent the selection
- theTextToken.tokenOffset = (**(theDocument->theText)).selStart + 1;
- theTextToken.tokenLength = ((**(theDocument->theText)).selEnd -
- (**(theDocument->theText)).selStart) -1;
- theTextToken.tokenWindow = theWindowPropToken.tokenWindowToken.tokenWindow;
-
-
- // now get the property- it's in the selection data
- myErr = AECoerceDesc(selectionData, typeType, &propDesc);
- GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty,
- sizeof(theProperty), &actualSize);
-
- // Combine the two into single token
- myTextProp.tokenTextToken = theTextToken;
- myTextProp.tokenProperty = theProperty;
-
- myErr = AECreateDesc(typeMyTextProp,(Ptr)&myTextProp,
- sizeof(myTextProp),value);
-
-
- if (propDesc.dataHandle) ignoreErr = AEDisposeDesc(&propDesc);
- if (newDesc.dataHandle) ignoreErr = AEDisposeDesc(&newDesc);
-
- return myErr;
-
- }
-
- if (newDesc.dataHandle)
- ignoreErr = AEDisposeDesc(&newDesc);
-
- return errAEWrongDataType;
- }
-
-
- OSErr MenuFormAbsolutePosition( const AEDesc *selectionData, AEDesc* result )
- {
- AEDesc itemDesc = {typeNull, NULL};
- short aCount,
- index;
- OSErr err;
-
- aCount = CountMenus();
-
- if (! aCount)
- return(errAEIllegalIndex);
-
- if ( typeAbsoluteOrdinal == selectionData->descriptorType )
- {
- err = noErr;
-
- switch (*(DescType *)*selectionData->dataHandle)
- {
- case kAEFirst:
- index = 1;
- break;
-
- case kAELast:
- index = aCount;
- break;
-
- case kAEMiddle:
- index = (aCount + 1) / 2;
- break;
-
- case kAEAny:
- index = (Random() % aCount) + 1;
- break;
-
- case kAEAll:
- err = AECreateList(NULL, 0 , false, result);
- if (noErr != err) goto done;
-
- for (index = 1; index <= aCount; index++)
- {
- err = GetDescOfNthMenu(index, &itemDesc);
- if (noErr != err) goto done;
-
- err = AEPutDesc(result, 0, &itemDesc);
- if (noErr != err) goto done;
-
- if (itemDesc.dataHandle)
- AEDisposeDesc(&itemDesc);
- }
-
- goto done; // We have created our list descriptor
- break; // so we can just tidy up and return.
-
- default:
- err = errAETypeError;
- }
- }
- else
- err = GetIntegerFromDescriptor( selectionData, &index );
-
- if (noErr != err) goto done;
-
- if (index < 0) // Handle negative indexes
- index = aCount + index + 1;
-
- if ( index > aCount || index <= 0 )
- err = errAEIllegalIndex;
- else
- err = GetDescOfNthMenu( index, result );
-
- done:
- (void)AEDisposeDesc( &itemDesc );
-
- return err;
- } // MenuFormAbsolutePosition
-
-
- OSErr MenuFormName( const AEDesc *selectionData, AEDesc* result )
- {
- Str255 name;
- OSErr err;
-
- // This tries to coerce it first
- err = GetPStringFromDescriptor( selectionData, name );
- if ( noErr != err ) goto done;
-
- err = GetDescOfNamedMenu( name, result );
-
- done:
- return(err);
- }
-
-
- pascal OSErr MenuFromNullAccessor( DescType wantClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused (container,theRefCon)
- #endif
-
- OSErr err;
-
- // Can only handle cWindow and cDocument
- if ( wantClass != cMenu )
- return errAEWrongDataType;
-
- // Can only handle typeNull and typeMyAppl
- if ( containerClass != typeNull && containerClass != typeMyAppl )
- return errAENoSuchObject;
-
- switch (form)
- {
- case formAbsolutePosition:
- err = MenuFormAbsolutePosition( selectionData, value );
- break;
-
- case formName:
- err = MenuFormName( selectionData, value );
- break;
-
- default:
- err = errAEBadTestKey;
- }
-
- return err;
- }
-
-
- pascal OSErr PropertyFromMenuAccessor(DescType wantClass,
- AEDesc *container,
- DescType containerClass,
- DescType form,
- AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(containerClass)
- #endif
-
- long itemCount,
- index;
- AEDesc resultDesc = {typeNull, NULL},
- aDesc = {typeNull, NULL},
- propDesc = {typeNull, NULL};
- Size actualSize;
- DescType returnedType;
- MenuToken theToken;
- MenuPropToken thePropertyToken;
- OSErr err;
-
- if (typeAEList == container->descriptorType)
- {
- err = AECreateList( NULL, 0 , false, value ); // Result will also be a list of items
- if (noErr != err) goto done;
- err = AECountItems( container, &itemCount );
- if (noErr != err) goto done;
-
- for ( index = 1; index <= itemCount; index++ ) // Do in forward order
- {
- err = AEGetNthDesc( container, index, typeWildCard, &returnedType, &aDesc );
- if ( noErr != err ) goto done;
- // Recursively call this routine
- // - could be another list.
- err = PropertyFromMenuAccessor( wantClass, &aDesc, aDesc.descriptorType,
- form, selectionData, &resultDesc, theRefCon );
-
- err = AEPutDesc( value, 0, &resultDesc ); // Add item to the end of our list
- if ( noErr != err ) goto done;
-
- (void)AEDisposeDesc( &aDesc );
- (void)AEDisposeDesc( &resultDesc );
- }
- }
- else
- { // get the window token - it's the container
-
- err = AECoerceDesc( container, typeMyMenu, &aDesc );
- if ( noErr != err ) goto done;
- GetRawDataFromDescriptor( &aDesc, (Ptr)&theToken,
- sizeof(theToken), &actualSize );
-
- // get the property - it's in the selection data
-
- err = AECoerceDesc( selectionData, typeType, &propDesc );
- if ( noErr != err ) goto done;
- GetRawDataFromDescriptor( &propDesc, (Ptr)&returnedType,
- sizeof(returnedType), &actualSize );
-
- // Combine the two into single token
-
- thePropertyToken.token = theToken;
- thePropertyToken.tokenProperty = returnedType;
-
- err = AECreateDesc( typeMyMenuProp, (Ptr)&thePropertyToken,
- sizeof( thePropertyToken ), value );
- }
-
- done:
- (void)AEDisposeDesc( &aDesc );
- (void)AEDisposeDesc( &propDesc );
- (void)AEDisposeDesc( &resultDesc );
-
- return(err);
- } // PropertyFromMenuAccessor
-
-
- OSErr MenuItemFormAbsolutePosition( MenuToken* containerToken, const AEDesc *selectionData, AEDesc* result )
- {
- AEDesc itemDesc = {typeNull, NULL};
- short aCount,
- index;
- OSErr err;
-
- aCount = CountMenuTokenItems( containerToken );
-
- if (! aCount)
- return(errAEIllegalIndex);
-
- if ( typeAbsoluteOrdinal == selectionData->descriptorType )
- {
- err = noErr;
-
- switch (*(DescType *)*selectionData->dataHandle)
- {
- case kAEFirst:
- index = 1;
- break;
-
- case kAELast:
- index = aCount;
- break;
-
- case kAEMiddle:
- index = (aCount + 1) / 2;
- break;
-
- case kAEAny:
- index = (Random() % aCount) + 1;
- break;
-
- case kAEAll:
- err = AECreateList(NULL, 0 , false, result);
- if (noErr != err) goto done;
-
- for (index = 1; index <= aCount; index++)
- {
- err = GetDescOfNthMenuItem( containerToken, index, &itemDesc );
- if (noErr != err) goto done;
-
- err = AEPutDesc(result, 0, &itemDesc);
- if (noErr != err) goto done;
-
- if (itemDesc.dataHandle)
- AEDisposeDesc(&itemDesc);
- }
-
- goto done; // We have created our list descriptor
- break; // so we can just tidy up and return.
-
- default:
- err = errAETypeError;
- }
- }
- else
- err = GetIntegerFromDescriptor( selectionData, &index );
-
- if (noErr != err) goto done;
-
- if (index < 0) // Handle negative indexes
- index = aCount + index + 1;
-
- if ( index > aCount || index <= 0 )
- err = errAEIllegalIndex;
- else
- err = GetDescOfNthMenuItem( containerToken, index, result );
-
- done:
- (void)AEDisposeDesc( &itemDesc );
-
- return err;
- } // MenuFormAbsolutePosition
-
-
- OSErr MenuItemFormName( MenuToken* containerToken, const AEDesc* selectionData, AEDesc* result )
- {
- Str255 name;
- OSErr err;
-
- // This tries to coerce it first
- err = GetPStringFromDescriptor( selectionData, name );
- if ( noErr != err ) goto done;
-
- err = GetDescOfNamedMenuItem( containerToken, name, result );
-
- done:
- return(err);
- }
-
-
- pascal OSErr MenuItemFromMenuAccessor( DescType wantClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused ( containerClass, theRefCon )
- #endif
-
- MenuToken containerToken;
- Size actualSize;
- OSErr err;
-
- // Can only handle cMenu
- if ( wantClass != cMenuItem )
- return errAEWrongDataType;
-
- // Can only handle typeMyMenu
- if ( container->descriptorType != typeMyMenu )
- return errAENoSuchObject;
-
- // Get the containing MenuToken
- GetRawDataFromDescriptor( container, (Ptr)&containerToken,
- sizeof( containerToken ), &actualSize );
-
- switch (form)
- {
- case formAbsolutePosition:
- err = MenuItemFormAbsolutePosition( &containerToken, selectionData, value );
- break;
-
- case formName:
- err = MenuItemFormName( &containerToken, selectionData, value );
- break;
-
- default:
- err = errAEBadTestKey;
- }
-
- return err;
- }
-
-
- pascal OSErr PropertyFromMenuItemAccessor(DescType wantClass,
- AEDesc *container,
- DescType containerClass,
- DescType form,
- AEDesc *selectionData,
- AEDesc *value,
- long theRefCon)
- {
- #ifdef __MWERKS__
- #pragma unused(containerClass)
- #endif
-
- long itemCount,
- index;
- AEDesc resultDesc = {typeNull, NULL},
- aDesc = {typeNull, NULL},
- propDesc = {typeNull, NULL};
- Size actualSize;
- DescType returnedType;
- MenuItemToken theToken;
- MenuItemPropToken thePropertyToken;
- OSErr err;
-
- if (typeAEList == container->descriptorType)
- {
- err = AECreateList( NULL, 0 , false, value ); // Result will also be a list of items
- if ( noErr != err ) goto done;
- err = AECountItems( container, &itemCount );
- if ( noErr != err ) goto done;
-
- for ( index = 1; index <= itemCount; index++ ) // Do in forward order
- {
- err = AEGetNthDesc( container, index, typeWildCard, &returnedType, &aDesc );
- if ( noErr != err ) goto done;
- // Recursively call this routine
- // - could be another list.
- err = PropertyFromMenuItemAccessor( wantClass, &aDesc, aDesc.descriptorType,
- form, selectionData, &resultDesc, theRefCon );
- if ( noErr != err ) goto done;
-
- err = AEPutDesc( value, 0, &resultDesc ); // Add item to the end of our list
- if ( noErr != err ) goto done;
-
- (void)AEDisposeDesc( &aDesc );
- (void)AEDisposeDesc( &resultDesc );
- }
- }
- else
- {
- err = AECoerceDesc(container, typeMyMenuItem, &aDesc);
- if ( noErr != err ) goto done;
- GetRawDataFromDescriptor(&aDesc, (Ptr)&theToken,
- sizeof(theToken), &actualSize);
-
- // get the property - it's in the selection data
-
- err = AECoerceDesc( selectionData, typeType, &propDesc );
- if ( noErr != err ) goto done;
- GetRawDataFromDescriptor( &propDesc, (Ptr)&returnedType,
- sizeof(returnedType), &actualSize );
-
- // Combine the two into single token
-
- thePropertyToken.token = theToken;
- thePropertyToken.tokenProperty = returnedType;
-
- err = AECreateDesc( typeMyMenuItemProp, (Ptr)&thePropertyToken,
- sizeof( thePropertyToken ), value );
- }
-
- done:
- (void)AEDisposeDesc(&aDesc);
- (void)AEDisposeDesc(&propDesc);
- (void)AEDisposeDesc(&resultDesc);
-
- return(err);
- } // PropertyFromMenuItemAccessor
-
-